import { FileService } from "../../services/file.service.js";
import { BadRequestError } from "../../utils/errors.js";
import { db } from "./../../config/sequelize.js";
import {
  calculateFileHash,
  calculateLargeFileHash,
} from "../../utils/file-utils.js";

const fileService = new FileService(db);

/**
 * 文件上传控制器
 */
export class FileUploadController {
  /**
   * 单文件上传
   */
  static async uploadFile(req, res) {
    console.log("上传文件", req.file);

    if (!req.file) {
      throw new BadRequestError("未上传文件");
    }
    // 使用中间件已创建的记录
    const fileRecord = req.fileRecord;
    try {
      const fileInfo = await fileService.saveFile({
        file: req.file,
        userId: req.user.id,
        type: req.body.type || "default",
      });
      // 更新记录状态
      await fileService.updateFileRecord(fileRecord.id, {
        status: "completed",
        file_path: fileInfo.path,
        completed_at: new Date(),
      });
      res.json({
        code: 200,
        success: true,
        data: fileInfo,
        message: "文件上传成功",
      });
    } catch (error) {
      // 上传失败更新状态
      await fileService.updateFileRecord(fileRecord.id, {
        status: "failed",
        error_message: error.message,
      });
      throw error;
    }
  }

  /**
   * 上传缩略图
   */
  static async uploadThumbnail(req, res) {
    if (!req.file) {
      throw new BadRequestError("未上传文件");
    }

    const fileInfo = await fileService.saveThumbnail({
      file: req.file,
      userId: req.user.id,
      type: req.body.type || "default",
    });

    res.json({
      code: 200,
      success: true,
      data: fileInfo,
      message: "文件上传成功",
    });
  }
  /**
   * 上传详情图（多文件上传）
   */
  static async uploadGallery(req, res) {
    if (!req.files || req.files.length === 0) {
      throw new BadRequestError("至少需要上传一个文件");
    }

    try {
      // 1. 处理所有上传的文件
      const fileResults = await Promise.all(
        req.files.map(async (file) => {
          // 2. 可在此处添加自定义逻辑（如压缩图片、生成缩略图等）
          return {
            name: file.filename,
            url: `/uploads/gallery/${file.filename}`, // 使用公开访问URL
            path: file.path, // 物理路径（仅服务端使用）
            size: file.size,
            type: file.mimetype,
            uploadedAt: new Date(),
          };
        })
      );

      // 3. 返回标准化响应
      res.json({
        code: 200,
        success: true,
        data: fileResults,
        message: `成功上传 ${fileResults.length} 个文件`,
      });
    } catch (error) {
      // 4. 统一错误处理
      throw new InternalServerError("文件处理失败: " + error.message);
    }
  }

  /**
   * 上传商品SKU图
   */
  static async uploadSku(req, res) {
    if (!req.file) {
      throw new BadRequestError("未上传分片文件");
    }
    const file = req.file;

    res.json({
      code: 200,
      success: true,
      data: file,
      message: "文件上传成功",
    });
  }
  /**
   * 获取文件列表
   */
  static async getFilesList(req, res) {
    const files = await fileService.getFileList(req.user.id);

    res.json({
      code: 200,
      success: true,
      data: files,
    });
  }
  /**
   * 分片上传初始化
   */
  static async initChunkUpload(req, res) {
    try {
      console.log("分片上传初始化:", req.validatedData);
      const { fileHash, fileName, fileSize, fileType, totalChunks } =
        req.validatedData;
      const userId = req.user.id;
      // 1. 检查文件是否已存在
      const existingFile = await fileService.checkFileExists(fileHash);
      console.log("检查文件是否已存在", existingFile);
      if (existingFile && existingFile.status === "completed") {
        return res.json({
          code: 200,
          success: true,
          data: {
            shouldUpload: false,
            uploadedChunks: existingFile.chunks?.map((c) => c.index) || [],
            fileId: existingFile.id,
          },
        });
      }
      // 计算或获取文件哈希
      // const fileHash = req.body.fileHash || (await calculateFileHash(file));
      // 2. 初始化分片上传
      const result = await fileService.createFileRecord({
        fileHash,
        fileName,
        fileSize,
        fileType,
        totalChunks,
        userId,
      });

      res.json({
        code: 200,
        success: true,
        data: {
          shouldUpload: result.shouldUpload,
          uploadedChunks: result.uploadedChunks,
          fileId: result.file.id,
          totalChunks: result.file.total_chunks,
        },
      });
    } catch (error) {
      console.error("初始化分片上传失败:", error);
      res.status(error.statusCode || 500).json({
        code: error.statusCode || 500,
        success: false,
        message: error.message,
      });
    }
  }

  /**
   * 上传分片
   */
  static async uploadChunk(req, res) {
    const { fileHash, chunkIndex, chunkHash } = req.validatedData;
    console.log("开始上传分片文件：", fileHash);
    if (!req.file) {
      throw new BadRequestError("未上传分片文件");
    }
    console.log("分片文件数据：", fileHash, chunkIndex, chunkHash, req.file);
    const chunkInfo = await fileService.saveChunk({
      fileHash,
      chunkIndex,
      chunkHash,
      chunkFile: req.file,
    });
    console.log("分片保存结果：", chunkInfo);
    res.json({
      code: 200,
      success: true,
      message: "分片上传成功",
    });
  }

  /**
   * 合并分片
   */
  static async mergeChunks(req, res) {
    const { fileHash } = req.validatedData;
    console.log("合并分片--fileHash：", fileHash);
    const fileInfo = await fileService.mergeChunks(fileHash);
    console.log("合并结果：", fileInfo);
    res.json({
      code: 200,
      success: true,
      data: fileInfo,
      message: "文件合并成功",
    });
  }

  /**
   * 获取上传进度
   */
  static async getUploadProgress(req, res) {
    const { fileHash } = req.params;

    const progress = await fileService.getUploadProgress(fileHash);

    res.json({
      code: 200,
      success: true,
      data: progress,
    });
  }
  /**
   * 删除文件
   */
  static async deleteFile(req, res) {
    const { fileId } = req.params;

    await fileService.deleteFile(fileId);

    res.json({
      code: 200,
      success: true,
      message: "文件删除成功",
    });
  }

  /**
   * 检测文件是否已存在
   */
  static async checkFileExists(req, res) {
    const { fileHash, filename } = req.query;

    const { exists, uploadedChunks = [] } = await fileService.checkFileExists(
      fileHash,
      filename
    );
    console.log("检测文件是否已存在--exists:", exists);
    res.json({
      code: 200,
      success: true,
      data: { shouldUpload: !exists, uploadedChunks },
    });
  }
}
